<template>
  <div class="yearPicker" :ref="yearPicker">
    <i class="el-icon el-input__icon el-range__icon" style="color: #a8abb2">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
        <path
          fill="currentColor"
          d="M128 384v512h768V192H768v32a32 32 0 1 1-64 0v-32H320v32a32 32 0 0 1-64 0v-32H128v128h768v64zm192-256h384V96a32 32 0 1 1 64 0v32h160a32 32 0 0 1 32 32v768a32 32 0 0 1-32 32H96a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h160V96a32 32 0 0 1 64 0zm-32 384h64a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64m0 192h64a32 32 0 1 1 0 64h-64a32 32 0 1 1 0-64m192-192h64a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64m0 192h64a32 32 0 1 1 0 64h-64a32 32 0 1 1 0-64m192-192h64a32 32 0 1 1 0 64h-64a32 32 0 1 1 0-64m0 192h64a32 32 0 1 1 0 64h-64a32 32 0 1 1 0-64"
        ></path>
      </svg>
    </i>
    <input
      class="_inner"
      :ref="inputLeft"
      v-model="data.startShowYear"
      @focus="onFocus"
      @click="clickInput"
      type="text"
      name="yearInput"
      @input="checkStartInput()"
      placeholder="开始时间"
    />
    <span>{{ props.sp }}</span>
    <input
      class="_inner"
      :ref="inputRight"
      v-model="data.endShowYear"
      @focus="onFocus"
      @click="clickInput"
      type="text"
      name="yearInput"
      @input="checkEndInput()"
      placeholder="结束时间"
    />
    <div class="_inner floatPanel" v-if="data.showPanel">
      <div class="_inner leftPanel">
        <div class="_inner panelHead">
          <i class="_inner" @click="onClickLeft">&lt;&lt;</i>
          {{ leftYearList[0] + '-' + leftYearList[9] }}
        </div>
        <div class="_inner panelContent">
          <div
            :class="{
              disabled: checkValidYear(item),
              oneSelected: item === data.startYear && oneSelected,
              startSelected: item === data.startYear,
              endSelected: item === data.endYear,
              _inner: true,
              betweenSelected: item > data.startYear && item < data.endYear
            }"
            v-for="item in leftYearList"
            :key="item"
          >
            <a
              :class="{
                cell: true,
                _inner: true,
                selected: item === data.startYear || item === data.endYear
              }"
              @click="onClickItem(item)"
              @mouseover="onHoverItem(item)"
            >
              {{ item }}
            </a>
          </div>
        </div>
      </div>
      <div class="_inner rightPanel">
        <div class="_inner panelHead">
          <i class="_inner" @click="onClickRight">&gt;&gt;</i>
          {{ rightYearList[0] + '-' + rightYearList[9] }}
        </div>
        <div class="_inner panelContent">
          <div
            :class="{
              disabled: checkValidYear(item),
              startSelected: item === data.startYear,
              endSelected: item === data.endYear,
              betweenSelected: item > data.startYear && item < data.endYear
            }"
            v-for="item in rightYearList"
            :key="item"
          >
            <a
              :class="{
                cell: true,
                _inner: true,
                selected: item === data.endYear || item === data.startYear
              }"
              @click="onClickItem(item)"
              @mouseover="onHoverItem(item)"
            >
              {{ item }}
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup name="YearPicker">
import { ElMessage } from 'element-plus'
import { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive, ref } from 'vue'

const emits = defineEmits(['updateTimeRange'])

const props = defineProps({
  labelWidth: {
    type: Number,
    default: 80
  },
  labelText: {
    type: String,
    default: '时间标签'
  },
  sp: {
    type: String,
    default: '至'
  },
  initYear: {
    startYear: '',
    endYear: ''
  },
  showYear: {
    startShowYear: '',
    endShowYear: ''
  },
  maxLength: {
    type: Number,
    default: 100
  }
})

const SELECT_STATE = {
  unselect: 0,
  selecting: 1,
  selected: 2
}

const data = reactive({
  itemBg: {},
  startShowYear: null,
  endShowYear: null,
  yearList: [],
  showPanel: false,
  startYear: null,
  endYear: null,
  curYear: 0,
  curSelectedYear: 0,
  curState: SELECT_STATE.unselect
})
const yearPicker = ref()
const inputLeft = ref()
const inputRight = ref()

const oneSelected = computed(() => {
  return data.curState === SELECT_STATE.selecting && (data.startYear === data.endYear || data.endYear == null)
})

const leftYearList = computed(() => {
  return data.yearList.slice(0, 10)
})
const rightYearList = computed(() => {
  return data.yearList.slice(10, 20)
})

const clickInput = (e) => {
  e.stopPropagation()
  return false
}

const checkValidYear = (iYear) => {
  if (props.initYear) {
    if (iYear > props.initYear.endYear) {
      return 1
    } else if (iYear < props.initYear.startYear) {
      return -1
    }
  }
  return 0
}

const checkStartInput = () => {
  if (isNaN(data.startShowYear)) {
    data.startShowYear = data.startYear
  } else {
    data.startYear = data.startShowYear * 1
  }
}

const checkEndInput = () => {
  if (isNaN(data.endShowYear)) {
    data.endShowYear = data.endYear
  } else {
    data.endYear = data.endShowYear * 1
  }
}
const changeYear = () => {
  if (data.startYear > data.endYear) {
    const tmp = data.endYear
    data.endYear = data.startYear
    data.startYear = tmp
  }
  if (props.initYear) {
    data.startYear = Math.max(data.startYear, props.initYear.startYear)
    data.endYear = Math.min(data.endYear, props.initYear.endYear)
  }
  data.startShowYear = data.startYear
  data.endShowYear = data.endYear

  if (data.startYear && data.endYear) {
    emits('updateTimeRange', data.startYear, data.endYear)
  } else {
    console.warn('WARN:年份不合法', data.startYear, data.endYear)
  }
}
const onHoverItem = (iYear) => {
  if (checkValidYear(iYear) !== 0) {
    return
  }
  if (data.curState === SELECT_STATE.selecting) {
    const tmpStart = data.curSelectedYear
    data.endYear = Math.max(tmpStart, iYear)
    data.startYear = Math.min(tmpStart, iYear)
  }
}
const onClickItem = (iYear) => {
  if (checkValidYear(iYear) !== 0) {
    return
  }

  if (data.curState === SELECT_STATE.unselect || data.curState === SELECT_STATE.selected) {
    data.startYear = iYear
    data.curSelectedYear = iYear
    data.endYear = data.startYear
    data.curState = SELECT_STATE.selecting
  } else if (data.curState === SELECT_STATE.selecting) {
    data.endShowYear = data.endYear
    data.startShowYear = data.startYear
    data.curState = SELECT_STATE.selected
    if (props.maxLength) {
      if (data.endYear - data.startYear > props.maxLength) {
        ElMessage.warning(`时间跨度不能大于${props.maxLength}年，默认选择开始日期的${props.maxLength}年`)
        data.endYear = data.startYear + props.maxLength
        data.endShowYear = data.endYear
      }
    }
    emits('updateTimeRange', data.startYear, data.endYear)

    setTimeout(() => {
      // 为动画留的时间，可优化
      data.showPanel = false
    }, 300)
  }
}
const onFocus = () => {
  nextTick(() => {
    data.showPanel = true
  })
}

const updateYearList = () => {
  let iStart = Math.floor(data.curYear / 10) * 10 - 10
  iStart = iStart < 0 ? 0 : iStart
  data.yearList = []
  for (let index = 0; index < 20; index++) {
    data.yearList.push(iStart + index)
  }
}
const closePanel = (e) => {
  if (!data.showPanel) {
    return
  }
  if (typeof e.target.className !== 'string' || e.target.className === '') {
    nextTick(() => {
      changeYear()
      data.showPanel = false
    })
    return
  }

  if (e.target.className.indexOf('_inner') === -1 || (e.target.name === 'yearInput' && e.target !== inputLeft.value && e.target !== inputRight.value)) {
    nextTick(() => {
      changeYear()
      data.showPanel = false
    })
  }

  e.stopPropagation()
  return false
}
const onClickLeft = () => {
  data.curYear = data.curYear * 1 - 10
  updateYearList()
}
const onClickRight = () => {
  data.curYear = data.curYear * 1 + 10
  updateYearList()
}

onBeforeMount(() => {
  data.curYear = new Date().getFullYear()
  updateYearList()
})
onBeforeUnmount(() => {
  document.removeEventListener('click', closePanel.bind(data))
  props.showYear.startShowYear = ''
  props.showYear.endShowYear = ''
})

onMounted(() => {
  document.addEventListener('click', closePanel.bind(data))
  if (props.showYear) {
    if (props.showYear.startShowYear != '') {
      data.startShowYear = props.showYear.startShowYear
    }
    if (props.showYear.endShowYear != '') {
      data.endShowYear = props.showYear.endShowYear
    }
  }
})
</script>

<style lang="scss" scoped>
.yearPicker {
  font-size: 14px;
  display: flex;
  align-items: center;
  position: relative;
  transition: all 0.3s;
  width: 100%;

  input:first-child {
    text-align: right;
  }

  background-color: #fff;

  span {
    padding: 0 8px;
    height: 32px;
    line-height: 32px;
  }

  border: 1px solid #eff1f3;
  height: 34px;
  line-height: 34px;
  border-radius: 4px;
  padding: 0 8px;
  box-sizing: border-box;

  .floatPanel {
    color: #606266;
    > div {
      width: 50%;
    }

    padding: 0 16px;
    position: absolute;
    display: flex;
    background-color: #fff;
    z-index: 2000;
    border-radius: 4px;
    width: 650px;
    height: 250px;
    top: 40px;
    left: -50px;
    box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);

    .panelContent {
      display: flex;
      flex-wrap: wrap;
      width: 100%;
      height: calc(100% - 70px);

      .disabled {
        .cell {
          color: #ccc !important;
        }
      }

      .oneSelected {
        border-top-right-radius: 24px;
        border-bottom-right-radius: 24px;
      }

      .startSelected {
        background-color: #f6f6f7;
        border-top-left-radius: 24px;
        border-bottom-left-radius: 24px;
      }

      .endSelected {
        background-color: #f6f6f7;
        border-top-right-radius: 24px;
        border-bottom-right-radius: 24px;
      }

      .betweenSelected {
        background-color: #f6f6f7;
      }

      > div {
        width: 75px;
        height: 48px;
        line-height: 48px;
        margin: 3px 0;
        // border-radius: 24px;
        text-align: center;

        a {
          color: #606266;
          display: inline-block;
          width: 60px;
          height: 36px;
          cursor: pointer;
          line-height: 36px;
          border-radius: 18px;
        }

        .selected {
          background-color: #409eff;
          color: #fff;
        }
      }
    }

    .panelHead {
      position: relative;
      height: 46px;
      line-height: 46px;
      text-align: center;

      i {
        position: absolute;
        cursor: pointer;

        &:hover {
          color: #3e77fc;
        }
      }
    }

    .rightPanel {
      padding-left: 8px;
    }

    .leftPanel .panelHead i {
      left: 20px;
    }

    .rightPanel .panelHead i {
      right: 20px;
    }
  }

  .floatPanel::before {
    content: '';
    height: 100%;
    position: absolute;
    left: 50%;
    width: 1px;
    border-left: 1px solid #e4e4e4;
  }
}

input {
  color: #606266;
  width: 39%;
  border: none;
  height: 32px;
  text-align: center;
  line-height: 32px;
  box-sizing: border-box;
  background-color: transparent;
  font-size: 12px;
}

input:focus {
  outline: none;
  background-color: transparent;
}

.yearPicker:hover {
  box-shadow: 0 0 0 1px #c0c4cc inset;
}

.dateIcon {
  position: absolute;
  right: 16px;
  top: 9px;
  color: #adb2bc;
}

.el-date-editor .el-range__icon {
  color: #a8abb2;
}
</style>
